﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using Web7.Ioc;
using System.Web.Mvc;
using Web7.Core.Context;
using Web7.Extensions;
using System.Web.Routing;
using Web7.Dispose;
using Web7.Core.BootStrapperTask;

namespace Web7.Core
{
    public class Web7ApplicationStart : DisposableObject
    {
        private readonly HttpApplication _httpApplication;
        private IWeb7ApplicationContext _appContext; //上下文
        private readonly AbstractContainerBuilder _containerBuilder;
        private readonly Func<IWeb7DependencyResolver, IDependencyResolver> _mvcResolverFactory;

        public Web7ApplicationStart(HttpApplication httpApplication, AbstractContainerBuilder containerBuilder, Func<IWeb7DependencyResolver, IDependencyResolver> mvcResolverFactory)
        {
            _mvcResolverFactory = mvcResolverFactory;
            _httpApplication = httpApplication;
            _containerBuilder = containerBuilder;
        }

        public static string Web7VersionInfo
        {
            get
            {
                //todo:web7版本信息
                return string.Empty;
            }
        }

        public static string Web7Version
        {
            get
            {
                //todo:web7版本号
                return string.Empty;
            }
        }

        public virtual void OnEndRequest(object sender, EventArgs e)
        {
            Dispose();
        }

        /// <summary>
        /// 获取Application
        /// </summary>
        /// <value>The application.</value>
        public HttpApplication Application
        {
            get
            {
                return _httpApplication;
            }
        }

        /// <summary>
        /// 启动web7一系列操作
        /// </summary>
        public virtual void Start()
        {
            //todo:log start
            using (var bootManager = CreateBootManager())
            {
                bootManager
                    .AddAppErrorHandler(OnApplicationError)
                    .InitializeContainer(() => _containerBuilder)
                    .AddContainerBuildingHandler(OnContainerBuilding)
                    .AddContainerBuildingCompleteHandler(OnContainerBuildingComplete)
                    .SetMvcResolverFactory(_mvcResolverFactory);
                _appContext = Boot(bootManager);

                //standard MVC registration:
                AreaRegistration.RegisterAllAreas();
                RegisterGlobalFilters(GlobalFilters.Filters);
                RegisterRoutes(RouteTable.Routes);
            }
        }


        /// <summary>
        /// 依赖容器管理准备启动事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void OnContainerBuilding(object sender, ContainerBuilderEventArgs e)
        {
        }

        /// <summary>
        /// 依赖容器管理启动成功事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void OnContainerBuildingComplete(object sender, ContainerBuilderEventArgs e)
        {
            
        }

        /// <summary>
        /// 应用程序错误处理事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void OnApplicationError(object sender, EventArgs e)
        {

        }

        public virtual void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }

        public virtual void RegisterRoutes(RouteCollection routes)
        {
        }

        /// <summary>
        /// 指定启动管理器，如果您想修改当前的启动管理器的具体操作，则重写此方法吧
        /// </summary>
        /// <param name="bootManager"><see cref="BootManager"/>应用程序启动管理器</param>
        protected virtual IWeb7ApplicationContext Boot(BootManager bootManager)
        {
            return bootManager.Boot();
        }

        /// <summary>
        /// 创建应用程序启动管理器
        /// </summary>
        /// <returns></returns>
        public virtual BootManager CreateBootManager()
        {
            return new BootManager(Application);
        }

        protected override void DisposeResources()
        {
            _appContext.IfNotNull(x => x.DisposeIfDisposable());
        }
    }
}
